//
//  SWCellTestCases.m
//  [SW] Weighted Grid Generator
//
//  Created by David Langford on 17/09/09.
//  Copyright 2009 Sentient Worlds. All rights reserved.
//

#import "SWCellTestCases.h"
#import "SWCell.h"

@implementation SWCellTestCases

// Test valid and invalid initialisations of of SWCell
- (void)testInitialisations
{
	// Valid case
	SWCell *validCell = [[SWCell alloc] initWithXPositionAt:0
												yPositionAt:0
											  widthInPixels:10
											 heightInPixels:10];
	STAssertNotNil(validCell, @"Initialise did not succeed with valid arguments");
	[validCell release];
	
	// Not valid case. All arguments are incorrect
	SWCell *inValidCellAllArguments = [[SWCell alloc] initWithXPositionAt:-1
												yPositionAt:-1
											  widthInPixels:0
											 heightInPixels:-4];
	STAssertNil(inValidCellAllArguments, @"Initialise should not have happened, all arguments were invalid");
	[inValidCellAllArguments release];
	
	// Not valid case. x position invalid
	SWCell *inValidCellXPosition = [[SWCell alloc] initWithXPositionAt:-15
												  yPositionAt:0
												widthInPixels:100
											   heightInPixels:100];
	STAssertNil(inValidCellXPosition, @"Initialise should not have happened, all arguments were invalid");
	[inValidCellXPosition release];
	
	// Not valid case. y position invalid
	SWCell *inValidCellYPosition = [[SWCell alloc] initWithXPositionAt:0
												  yPositionAt:-20
												widthInPixels:100
											   heightInPixels:100];
	STAssertNil(inValidCellYPosition, @"Initialise should not have happened, the x position is not allowed to be negative");
	[inValidCellYPosition release];
	
	// Not valid case. width invalid (0)
	SWCell *inValidCellWidth0 = [[SWCell alloc] initWithXPositionAt:0
												  yPositionAt:0
												widthInPixels:0
											   heightInPixels:100];
	STAssertNil(inValidCellWidth0, @"Initialise should not have happened, the width is not allowed to be 0");
	[inValidCellWidth0 release];
	
	// Not valid case. width invalid (negative value)
	SWCell *inValidCellWidthNegative = [[SWCell alloc] initWithXPositionAt:0
												  yPositionAt:0
												widthInPixels:-5
											   heightInPixels:100];
	STAssertNil(inValidCellWidthNegative, @"Initialise should not have happened, the width is not allowed to be negative");
	[inValidCellWidthNegative release];
	
	// Not valid case. height invalid (0)
	SWCell *inValidCellHeight0 = [[SWCell alloc] initWithXPositionAt:0
												  yPositionAt:0
												widthInPixels:100
											   heightInPixels:0];
	STAssertNil(inValidCellHeight0, @"Initialise should not have happened, the height is not allowed to be 0");
	[inValidCellHeight0 release];
	
	// Not valid case. height invalid (negative value)
	SWCell *inValidCellHeightNegative = [[SWCell alloc] initWithXPositionAt:0
												  yPositionAt:0
												widthInPixels:100
											   heightInPixels:-1];
	STAssertNil(inValidCellHeightNegative, @"Initialise should not have happened, the height is not allowed to be negative");
	[inValidCellHeightNegative release];
}


- (void)testAsNSArray
{
	// Create a valid cell
	SWCell *validCell = [[SWCell alloc] initWithXPositionAt:0
												yPositionAt:0
											  widthInPixels:10
											 heightInPixels:10];
	// Change the values, set the weight
	int originalXInPixels = 100;
	int originalYInPixels = 40;
	int originalWidthInPixels = 20;
	int originalHeightInPixels = 10;
	double originalWeight = 10.5;
	validCell.xInPixels = originalXInPixels;
	validCell.yInPixels = originalYInPixels;
	validCell.widthInPixels = originalWidthInPixels;
	validCell.heightInPixels = originalHeightInPixels;
	validCell.weight = originalWeight;
	
	// Get the array
	double destinationWidthInPixels = 200.0;
	double destinationHeightInPixels = 200.0;
	double destinationWidthInUnits = 2;
	double destinationHeightInUnits = 4;
	double destinationXOffsetInUnits = 0.5;
	double destinationYOffsetInUnits = 0.5;
	
	NSArray *retrievedArray = [validCell asNSArrayWithDestinationWidthInPixels: destinationWidthInPixels
												 destinationAreaHeightInPixels: destinationHeightInPixels
													   destinationWidthInUnits: destinationWidthInUnits
													  destinationHeightInUnits: destinationHeightInUnits
															destinationXOffset: destinationXOffsetInUnits
															destinationYOffset: destinationYOffsetInUnits];
	
	// Get the expected Values;
	// Need to change from pixels to units, then scale using the destination width and height. 
	double expectedXPosition = (originalXInPixels/destinationWidthInPixels)*destinationWidthInUnits;
	double expectedYPosition = (originalYInPixels/destinationHeightInPixels)*destinationHeightInUnits;
	double expectedWidth = (originalWidthInPixels/destinationWidthInPixels)*destinationWidthInUnits;
	double expectedHeight = (originalHeightInPixels/destinationHeightInPixels)*destinationHeightInUnits;
	double expectedWeight = originalWeight;
	
	// Handle the fact that we are moving the origin from the top right to the middle and the y-axis is flipped (for both grid and cell;
	expectedXPosition = expectedXPosition - destinationWidthInUnits/2;
	expectedYPosition = expectedYPosition - destinationHeightInUnits/2;
	expectedXPosition = expectedXPosition + expectedWidth/2;
	expectedYPosition = expectedYPosition + expectedHeight/2;
	expectedYPosition = expectedYPosition*-1;
	
	// Apply offsets
	expectedXPosition = expectedXPosition + destinationXOffsetInUnits;
	expectedYPosition = expectedYPosition + destinationYOffsetInUnits;
	
	// Compare the values
	STAssertEqualsWithAccuracy(expectedXPosition, [[retrievedArray objectAtIndex:0] doubleValue], 0.000001, @"The x position is not correct");
	STAssertEqualsWithAccuracy(expectedYPosition, [[retrievedArray objectAtIndex:1] doubleValue], 0.000001, @"The y position is not correct");
	STAssertEqualsWithAccuracy(expectedWidth, [[retrievedArray objectAtIndex:2] doubleValue], 0.000001, @"The width is not correct");
	STAssertEqualsWithAccuracy(expectedHeight, [[retrievedArray objectAtIndex:3] doubleValue], 0.000001, @"The height is not correct");
	STAssertEqualsWithAccuracy(expectedWeight, [[retrievedArray objectAtIndex:4] doubleValue], 0.000001, @"The weight is not correct");
	
	
	// Release the cell
	[validCell release];
}

@end
